package com.yyfax.pay.third.facade.quickpay;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yyfax.commons.http.HttpUtil;
import com.yyfax.pay.common.enums.PayModeEnum;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.enums.PayTypeEnum;
import com.yyfax.pay.common.enums.PaymentEnum;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.third.model.to.quickpay.AuthenticationQuickPayContent;
import com.yyfax.pay.third.model.to.quickpay.AuthenticationQuickPayParams;
import com.yyfax.pay.third.model.to.quickpay.PayOrderQuickPayContent;
import com.yyfax.pay.third.model.to.quickpay.PayOrderQuickPayParams;
import com.yyfax.pay.third.model.to.quickpay.QueryOrderQuickPayContent;
import com.yyfax.pay.third.model.to.quickpay.QueryOrderQuickPayParams;
import com.yyfax.pay.third.model.to.quickpay.QuickPayConstant;
import com.yyfax.pay.third.model.to.quickpay.SendAuthenticationVerifyCodeQuickPayContent;
import com.yyfax.pay.third.model.to.quickpay.SendAuthenticationVerifyCodeQuickPayParams;
import com.yyfax.pay.third.model.to.quickpay.SendVerifyCodeQuickPayContent;
import com.yyfax.pay.third.model.to.quickpay.SendVerifyCodeQuickPayParams;
import com.yyfax.pay.third.service.PayInfoConstantService;

/**
 * 快钱API
 * 
 * @author xiemh
 * @date 2017-04-11 21:37:25
 * @since v1.0.0
 */
@Service("quickPayApi")
public class QuickPayApi {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private static int CONNECT_TIMEOUT = 10000;
	private static int READ_TIMEOUT = 15000;
	private static String CHARSET = "UTF-8";
	private static String CONTENT_TYPE = "application/xml";

	@Autowired
	private PayInfoConstantService quickPayInfoUtil;

	/**
	 * 请求动态码验证码
	 * 
	 * @author xiemh
	 * @date 2017-04-13 20:35:24
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public SendVerifyCodeQuickPayContent sendVerifyCode(SendVerifyCodeQuickPayParams params) throws Exception {

		String result = httpPost(params.getMerchantCode(), params.getReqContent(), params.getReqUrl());
		SendVerifyCodeQuickPayContent content = SendVerifyCodeQuickPayContent.fromXml(result);
		content.setReqUrl(params.getReqUrl());
		content.setReqContent(params.getReqContent());
		content.setRspContent(result);
		return content;
	}

	/**
	 * 查询订单
	 * 
	 * @author xiemh
	 * @date 2017-04-13 20:35:59
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public QueryOrderQuickPayContent queryOrder(QueryOrderQuickPayParams params) throws Exception {

		String result = httpPost(params.getMerchantCode(), params.getReqContent(), params.getReqUrl());
		QueryOrderQuickPayContent content = QueryOrderQuickPayContent.fromXml(result);
		content.setReqUrl(params.getReqUrl());
		content.setReqContent(params.getReqContent());
		content.setRspContent(result);
		return content;
	}

	/**
	 * 发送鉴权验证码
	 * 
	 * @author xiemh
	 * @date 2017-04-13 20:36:08
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public SendAuthenticationVerifyCodeQuickPayContent sendAuthenticationVerifyCode(SendAuthenticationVerifyCodeQuickPayParams params)
			throws Exception {

		String result = httpPost(params.getMerchantCode(), params.getReqContent(), params.getReqUrl());
		SendAuthenticationVerifyCodeQuickPayContent content = SendAuthenticationVerifyCodeQuickPayContent.fromXml(result);
		content.setReqUrl(params.getReqUrl());
		content.setReqContent(params.getReqContent());
		content.setRspContent(result);
		return content;
	}

	/**
	 * 鉴权
	 * 
	 * @author xiemh
	 * @date 2017-04-13 20:36:17
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public AuthenticationQuickPayContent authentication(AuthenticationQuickPayParams params) throws Exception {

		String result = httpPost(params.getMerchantCode(), params.getReqContent(), params.getReqUrl());
		AuthenticationQuickPayContent content = AuthenticationQuickPayContent.fromXml(result);
		content.setReqUrl(params.getReqUrl());
		content.setReqContent(params.getReqContent());
		content.setRspContent(result);
		return content;
	}

	/**
	 * 支付
	 * 
	 * @author xiemh
	 * @date 2017-04-13 20:35:48
	 * @since v1.0.0
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public PayOrderQuickPayContent payOrder(PayOrderQuickPayParams params) throws Exception {

		String result = httpPost(params.getMerchantCode(), params.getReqContent(), params.getReqUrl());
		PayOrderQuickPayContent content = PayOrderQuickPayContent.fromXml(result);
		content.setReqUrl(params.getReqUrl());
		content.setReqContent(params.getReqContent());
		content.setRspContent(result);
		return content;
	}

	/**
	 * http请求
	 * 
	 * @author xiemh
	 * @date 2017-04-17 08:57:25
	 * @since v1.0.0
	 * @param constant
	 * @param reqXmlBody
	 * @param url
	 * @return
	 * @throws Exception
	 */
	private String httpPost(String merchantCode, String reqXmlBody, String url) throws Exception {

		QuickPayConstant constant = quickPayInfoUtil.getMerchantInfo(QuickPayConstant.class, merchantCode, PaymentEnum.QUICK_PAY, PayTypeEnum.AUTH,
				PayModeEnum.AUTH_PAY);

		Map<String, String> headersMap = new HashMap<>();

		HttpUtil.initHttpsURLConnection(constant.getKeyStorePassword(), constant.getKeyStorePath(), null);
		String result = HttpUtil.postBody(url, reqXmlBody, headersMap, CONTENT_TYPE, CHARSET, constant.getKeyStoreUserName(),
				constant.getKeyStorePassword(), CONNECT_TIMEOUT, READ_TIMEOUT);

		logger.info("快钱请求：：url:{}，req:{},rsp:{}", url, reqXmlBody, result);

		if (StringUtils.isBlank(result)) {
			throw new YYPayException(PayRspCodeEnum.PAY_CODE_DEALING, "请求结果为空");
		}
		return result;
	}

}
